package cn.tedu.lbs.marketing.web.filter;

import cn.tedu.lbs.marketing.web.util.AuthenticationContextUtil;
import com.tarena.lbs.base.protocol.exception.BusinessException;
import com.tarena.lbs.common.passport.encoder.JwtEncoder;
import com.tarena.lbs.common.passport.principle.UserPrinciple;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

/**
 * 实现认证过滤器逻辑
 */
@Component
@Slf4j
@Order(200)
public class AuthenticationFilter implements Filter {
    @Autowired
    private JwtEncoder<UserPrinciple> jwtEncoder;
    /**
     * servlet过滤器执行过滤的核心方法
     * 案例1: 让这个过滤器的过滤代码生效 看到过滤效果 请求经过这个过滤器
     * @param request 请求对象 Servlet协议请求 当前环境一定是HttpServletRequest
     * @param response 请求对象 Servlet协议响应 当前环境一定是HttpServletResponse 如果用过滤器拦截
     *                 相当于使用这个response输出数据
     * @param chain 连接整体过滤器的一个 管道对象 -- 过滤链
     * @throws IOException
     * @throws ServletException
     */
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        log.info("认证过滤器 解析 jwt 获取认证对象开始");
        Thread thread = Thread.currentThread();
        log.info("当前线程:{}",thread.getName());
        //1.判断当前ServletRequest
        if (request instanceof HttpServletRequest){
            //才能进入 认证解析
            //2.从头里Authorization 获取 jwt
            HttpServletRequest httpRequest=(HttpServletRequest)request;
            String jwt = httpRequest.getHeader("Authorization");
            //3.判断jwt非空
            if (StringUtils.isNotEmpty(jwt)){
                //4.解析 jwtEncoder 获取userPrinciple对象
                try{
                    UserPrinciple userPrinciple = jwtEncoder.getLoginFromToken(jwt, UserPrinciple.class);
                    // 想办法向后传递参数
                    AuthenticationContextUtil.save(userPrinciple);
                }catch (BusinessException e){
                    log.error("jwt在过滤器中解析失败",e);
                }
            }
        }
        //过滤器对接框架下游代码 需要执行过滤连方法
        chain.doFilter(request,response);
        //如果参数保存 需要清除参数 [为什么要强调清空] 避免线程复用的时候 数据冲突
        AuthenticationContextUtil.clear();
    }
}
